package com.zhang.pdf.utils;

import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

public class ExportExcelPdf {
	private static final BaseColor BORDER_COLOR = new BaseColor(240, 255, 255);

	private static final float TABLE_BORDER_WIDTH = 0.5F;

	public static void createExcel(String thName, String javaBeanName, List<?> excelData, String path, String fileName) throws IOException {
		File file1 = new File(path);
		if (!file1.exists() && !file1.isDirectory())
			file1.mkdirs();
		path = path + fileName;
		String[] thNamesplit = thName.split(",");
		String[] javaBeanNamesplit = javaBeanName.split(",");
		HSSFWorkbook wkb = new HSSFWorkbook();
		HSSFSheet sheet = wkb.createSheet(fileName);
		for (int i = 0; i < thNamesplit.length; i++){
		    if(i == 0){
	            sheet.setColumnWidth(i, thNamesplit[i].getBytes().length*4*256);
		    }else{
	            sheet.setColumnWidth(i, thNamesplit[i].getBytes().length*2*256);
		    }
        }
		HSSFRow row1 = sheet.createRow(0);
		for (int i = 0; i < thNamesplit.length; i++){
            row1.createCell(i).setCellValue(thNamesplit[i]);
		}
		int row = 1;
		for (int j = 0; j < excelData.size(); j++) {
			Map<String, Object> map = object2Map(excelData.get(j));
			HSSFRow row2 = sheet.createRow(row);
			for (int k = 0; k < javaBeanNamesplit.length; k++) {
				if (map.get(javaBeanNamesplit[k]) == null) {
					row2.createCell(k).setCellValue("");
				} else {
					row2.createCell(k).setCellValue(map.get(javaBeanNamesplit[k]).toString());
				}
			}
			row++;
		}
		FileOutputStream output = new FileOutputStream(path);
		wkb.write(output);
		output.flush();
		output.close();
	}

	public static Map<String, Object> object2Map(Object obj) {
		Map<String, Object> map = new HashMap<>();
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		if (obj == null)
			return map;
		Class<?> clazz = obj.getClass();
		Field[] fields = clazz.getDeclaredFields();
		try {
			for (Field field : fields) {
				if (field.getGenericType().toString().equals("class java.util.Date")) {
					field.setAccessible(true);
					if (field.get(obj) != null)
						map.put(field.getName(), df.format(field.get(obj)));
				} else {
					field.setAccessible(true);
					map.put(field.getName(), field.get(obj));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return map;
	}

	public static void createPdf(String thName, String javaBeanName, List<?> excelData, String path,
			HttpServletResponse response) throws IOException {
		path = path + "/pdf/";
		String fileName = (new Date()).getTime() + "_" + (new Random()).nextInt(10000) + ".pdf";
		File file1 = new File(path);
		if (!file1.exists() && !file1.isDirectory())
			file1.mkdirs();
		path = path + fileName;
		String[] thNamesplit = thName.split(",");
		String[] javaBeanNamesplit = javaBeanName.split(",");
		Document document = new Document();
		try {
			PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(path));
			document.open();
			BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", false);
			Font font = new Font(bfChinese, 10.0F, 0, BaseColor.BLACK);
			PdfPTable phhead = new PdfPTable(thNamesplit.length);
			for (int i = 0; i < thNamesplit.length; i++)
				phhead.addCell(getJiedianPdfPCell(getPhrase(thNamesplit[i], font)));
			PdfPTable ph = new PdfPTable(thNamesplit.length);
			for (int j = 0; j < excelData.size(); j++) {
				Map<String, Object> map = object2Map(excelData.get(j));
				for (int k = 0; k < javaBeanNamesplit.length; k++) {
					if (map.get(javaBeanNamesplit[k]) == null) {
						ph.addCell(getJiedianPdfPCell(getPhrase(" ", font)));
					} else {
						ph.addCell(getJiedianPdfPCell(getPhrase(map.get(javaBeanNamesplit[k]).toString(), font)));
					}
				}
			}
			document.add((Element) phhead);
			document.add((Element) ph);
			document.newPage();
			document.close();
			writer.close();
			File file = new File(path);
			response.setContentType("application/pdf");
			response.addHeader("Content-Disposition", "attachment; filename=" + fileName + ".pdf");
			byte[] buffer = new byte[1024];
			FileInputStream fis = null;
			BufferedInputStream bis = null;
			try {
				fis = new FileInputStream(file);
				bis = new BufferedInputStream(fis);
				ServletOutputStream servletOutputStream = response.getOutputStream();
				int k = bis.read(buffer);
				while (k != -1) {
					servletOutputStream.write(buffer, 0, k);
					k = bis.read(buffer);
				}
			} catch (IOException ex) {
				ex.printStackTrace();
			} finally {
				if (bis != null)
					try {
						bis.close();
					} catch (IOException iOException) {
					}
				if (fis != null)
					try {
						fis.close();
					} catch (IOException iOException) {
					}
			}
		} catch (DocumentException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} finally {
		}
	}

	public static Phrase getPhrase(String s, Font font) {
		return new Phrase(s, font);
	}

	public static PdfPCell getPdfPCell(Phrase p) {
		PdfPCell cell = new PdfPCell(p);
		cell.setBorderColor(BORDER_COLOR);
		cell.setBorderWidthTop(0.5F);
		cell.setBorderWidthBottom(0.5F);
		cell.setBorderWidthLeft(0.5F);
		cell.setBorderWidthRight(0.5F);
		cell.setHorizontalAlignment(0);
		return cell;
	}

	public static PdfPCell getCenterPdfPCell(Phrase p) {
		PdfPCell cell = new PdfPCell(p);
		cell.setBorderColor(BORDER_COLOR);
		cell.setBorderWidthTop(0.5F);
		cell.setBorderWidthBottom(0.5F);
		cell.setBorderWidthLeft(0.5F);
		cell.setBorderWidthRight(0.5F);
		cell.setHorizontalAlignment(1);
		return cell;
	}

	public static PdfPCell getJiedianPdfPCell(Phrase p) {
		PdfPCell cell = new PdfPCell(p);
		cell.setBorderWidthTop(0.5F);
		cell.setBorderWidthBottom(0.5F);
		cell.setBorderWidthLeft(0.5F);
		cell.setBorderWidthRight(0.5F);
		cell.setHorizontalAlignment(0);
		return cell;
	}
}
